﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace QLab.UserControls
{
	public partial class EditableTextBlock : UserControl
	{

		#region Constructor

		public EditableTextBlock()
		{
			InitializeComponent();
			base.Focusable = true;
			base.FocusVisualStyle = null;
		}

		#endregion Constructor

		#region Member Variables

		// We keep the old text when we go into editmode
		// in case the user aborts with the escape key
		private string oldText;

		#endregion Member Variables

		#region Properties

		public string Text
		{
			get { return (string)GetValue(TextProperty); }
			set { SetValue(TextProperty, value); }
		}
		public static readonly DependencyProperty TextProperty =
			DependencyProperty.Register(
			"Text",
			typeof(string),
			typeof(EditableTextBlock),
			new PropertyMetadata(""));

		public bool IsEditable
		{
			get { return (bool)GetValue(IsEditableProperty); }
			set { SetValue(IsEditableProperty, value); }
		}
		public static readonly DependencyProperty IsEditableProperty =
			DependencyProperty.Register(
			"IsEditable",
			typeof(bool),
			typeof(EditableTextBlock),
			new PropertyMetadata(true));

		public bool IsInEditMode
		{
			get
			{
				if (IsEditable)
					return (bool)GetValue(IsInEditModeProperty);
				else
					return false;
			}
			set
			{
				if (IsEditable)
				{
					oldText = Text;
					SetValue(IsInEditModeProperty, value);
				}
			}
		}
		public static readonly DependencyProperty IsInEditModeProperty =
			DependencyProperty.Register(
			"IsInEditMode",
			typeof(bool),
			typeof(EditableTextBlock),
			new PropertyMetadata(false));

		public string TextFormat
		{
			get { return (string)GetValue(TextFormatProperty); }
			set
			{
				if (value == "") value = "{0}";
				SetValue(TextFormatProperty, value);
			}
		}
		public static readonly DependencyProperty TextFormatProperty =
			DependencyProperty.Register(
			"TextFormat",
			typeof(string),
			typeof(EditableTextBlock),
			new PropertyMetadata("{0}"));

		public string FormattedText
		{
			get { return String.Format(TextFormat, Text); }
		}

		#endregion Properties

		#region Event Handlers

		// Invoked when we enter edit mode.
		void TextBox_Loaded(object sender, RoutedEventArgs e)
		{
			TextBox txt = sender as TextBox;
			oldText = Text;
			// Give the TextBox input focus
			txt.Focus();

			txt.SelectAll();
		}

		// Invoked when we exit edit mode.
		void TextBox_LostFocus(object sender, RoutedEventArgs e)
		{
			if (this.IsInEditMode)
				RaiseEvent(new RoutedEventArgs(EditFinishedEvent, this));
			this.IsInEditMode = false;
		}

		// Invoked when the user edits the annotation.
		void TextBox_KeyDown(object sender, KeyEventArgs e)
		{
			if (e.Key == Key.Enter)
			{
				this.IsInEditMode = false;
				RaiseEvent(new RoutedEventArgs(EditFinishedEvent, this));
				e.Handled = true;
			}
			else if (e.Key == Key.Escape)
			{
				Text = oldText;
				this.IsInEditMode = false;
				RaiseEvent(new RoutedEventArgs(EditCanceledEvent, this));
				e.Handled = true;
			}
		}

		#endregion Event Handlers

		#region Events

		public static readonly RoutedEvent EditCanceledEvent = EventManager.RegisterRoutedEvent(
			"EditCanceled", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(EditableTextBlock));

		public event RoutedEventHandler EditCanceled
		{
			add { AddHandler(EditCanceledEvent, value); }
			remove { RemoveHandler(EditCanceledEvent, value); }
		}

		public static readonly RoutedEvent EditFinishedEvent = EventManager.RegisterRoutedEvent(
			"EditFinished", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(EditableTextBlock));

		public event RoutedEventHandler EditFinished
		{
			add { AddHandler(EditFinishedEvent, value); }
			remove { RemoveHandler(EditFinishedEvent, value); }
		}

		#endregion
	}
}
